home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / PBLIB1 / UNITS / OBJSTRA.INC < prev    next >
Text File  |  1994-04-30  |  14KB  |  562 lines

  1.  
  2. {SECTION STR_object }
  3. Procedure STR_object.init;
  4. var  nbytes: Word;
  5.      st : string[1];
  6.      begin
  7.      GetMem (strptr, 1);
  8.      st := '';
  9.      Move (st, strptr^, 1);
  10.      end;
  11.  
  12.  
  13. procedure STR_object.dispose;
  14. var  nbytes: Word;
  15.       begin
  16.       IF strptr <> NIL then
  17.           begin
  18.           nbytes := Length(strptr^) + 1;
  19.           FreeMem (strptr, nbytes);
  20.           strptr := NIL;
  21.           end;
  22.       end;
  23.  
  24.  
  25. Function STR_object.store (st: String): boolean;
  26. var  nbytes: Word;
  27.      begin
  28.      if strptr <> NIL then dispose;
  29.      nbytes := Length (st) + 1;
  30.      IF MaxAvail < nbytes then  store := False
  31.      else begin
  32.           GetMem (strptr, nbytes);
  33.           Move (st, strptr^, nbytes);
  34.           store := True;
  35.           end;
  36.       end;
  37.  
  38.  
  39. Function STR_object.fetch: String;
  40.       begin
  41.       IF strptr = NIL then
  42.            fetch := ''
  43.       ELSE fetch := strptr^;
  44.       end;
  45.  
  46.  
  47. Procedure STR_object.dump;
  48.       begin
  49.       writeln('STR_object dump: ','{',seg(strptr):5,':',ofs(strptr):4,'}',
  50.                 '   ',length(strptr^),'  ',strptr^);
  51.       end;
  52.  
  53.  
  54.  
  55. {SECTION STRA_object }
  56. Procedure STRA_object.init(max : integer);
  57. var l : longint;
  58.     i : integer;
  59.      begin
  60.      arrayptr    := NIL;
  61.      arraymax    := 0;
  62.      arrayused   := 0;
  63.      arraysorted := true;
  64.      l := sizeof(STR_object) * max;
  65.      if memavail > l then
  66.           begin
  67.           getmem(arrayptr,l);
  68.           arraymax := max;
  69.           arrayused := 0;
  70.           for i := 1 to arraymax do arrayptr^[i].init;
  71.           modified    := false;
  72.           end;
  73.      end;
  74.  
  75.  
  76. procedure STRA_object.done;
  77. var l : longint;
  78.     i : integer;
  79.     ok : boolean;
  80.      begin
  81.      l := sizeof(STR_object) * arraymax;
  82.      IF (arrayptr <> NIL) and (l > 0) then
  83.           begin
  84.           for i := 1 to arraymax do arrayptr^[i].dispose;
  85.           FreeMem (arrayptr,l);
  86.           arrayptr := NIL;
  87.           end;
  88.      arrayused := 0;
  89.      arraysorted := false;
  90.      end;
  91.  
  92.  
  93.  
  94. Procedure STRA_object.clear;
  95. var i  : integer;
  96.     ok : boolean;
  97.      begin
  98.      if arrayused < 1 then exit;
  99.      if arrayptr <> NIL then
  100.           begin
  101.           for i := 1 to arrayused do ok := arrayptr^[i].store('');
  102.           arrayused := 0;
  103.           modified  := false;
  104.           end;
  105.      end;
  106.  
  107.  
  108. Function  STRA_object.Count : integer;
  109.      begin
  110.      Count := arrayused;
  111.      end;
  112.  
  113.  
  114. Function  STRA_object.sorted : boolean;
  115.      begin
  116.      sorted := arraysorted;
  117.      end;
  118.  
  119.  
  120. Function  STRA_object.ArrayMaxSize : integer;
  121.      begin
  122.      ArrayMaxSize := arraymax;
  123.      end;
  124.  
  125.  
  126. Function STRA_object.append(st : string) : boolean;
  127. var OK : boolean;
  128.      begin
  129.      OK := false;
  130.      if (arrayused < arraymax) and (MaxAvail > (length(st)+10)) then
  131.           begin
  132.           inc(arrayused);
  133.           OK := arrayptr^[arrayused].Store(st);
  134.           arraysorted := false;
  135.           modified    := true;
  136.           end;
  137.      append := OK;
  138.      end;
  139.  
  140.  
  141.  
  142. Function STRA_object.appendpush(st : string) : boolean;
  143. var OK : boolean;
  144.      begin
  145.      OK := true;
  146.      if (arrayused = arraymax) then ok := deletestr(1);
  147.      if OK then OK := STRA_object.storeN(arraymax,st);
  148.      appendpush := OK;
  149.      end;
  150.  
  151.  
  152.  
  153. Function STRA_object.storeN (n : integer; st : string): boolean;
  154. var OK : boolean;
  155.      begin
  156.      OK := false;
  157.      if (n > 0) and (n <= arraymax) and (MaxAvail > (length(st)+10)) then
  158.           begin
  159.           if n > arrayused then arrayused := n;
  160.           OK := arrayptr^[n].Store(st);
  161.           modified    := true;
  162.           arraysorted := false;
  163.           end;
  164.      storeN := OK;
  165.      end;
  166.  
  167.  
  168. Function STRA_object.fetchN(n : integer) : string;
  169. var s : string;
  170.      begin
  171.      s := '';
  172.      if (n > 0) and (n <= arrayused) then
  173.           begin
  174.           s := arrayptr^[n].fetch;
  175.           end;
  176.      fetchN := s;
  177.      end;
  178.  
  179.  
  180. Function  STRA_object.fetchString(n : integer) : string;
  181.     begin
  182.     fetchString := STRA_object.fetchN(n);
  183.     end;
  184.  
  185.  
  186. Function  STRA_object.fetchInteger(n : integer) : integer;
  187.     begin
  188.     fetchInteger := StrInt(STRA_object.fetchN(n));
  189.     end;
  190.  
  191.  
  192. Function  STRA_object.fetchLongInt(n : integer) : longint;
  193.     begin
  194.     fetchLongInt := StrLong(STRA_object.fetchN(n));
  195.     end;
  196.  
  197.  
  198. Function  STRA_object.fetchreal(n : integer) : real;
  199.     begin
  200.     fetchreal := StrReal(STRA_object.fetchN(n));
  201.     end;
  202.  
  203.  
  204. Function  STRA_object.fetchboolean(n : integer) : boolean;
  205. var result : boolean;
  206.     s      : string;
  207.     begin
  208.     result := false;
  209.     s := UpCaseStr(STRA_object.fetchN(n));
  210.     if      s = 'YES' then result := true
  211.     else if s = 'TRUE' then result := true;
  212.     fetchboolean := result;
  213.     end;
  214.  
  215.  
  216. Function STRA_object.LinearFind(st : string) : integer;
  217. var n : integer;
  218.     found : boolean;
  219.     s     : string;
  220.      begin
  221.      n := 0;
  222.      s := UpCaseStr(st);
  223.      if (arrayused > 0) then
  224.           begin
  225.           found := false;
  226.           while (n < arrayused) and not found do
  227.                begin
  228.                inc(n);
  229.                if s = arrayptr^[n].fetch then found := true;
  230.                end;
  231.           end;
  232.      if not found then n := 0;
  233.      linearfind := n;
  234.      end;
  235.  
  236.  
  237.  
  238. Function STRA_object.linearsearch(st : string; mode : byte) : integer;
  239. var n : integer;
  240.     found : boolean;
  241.     s     : string;
  242.      begin  {mode 0 = exact; 1 = GE; 2 = LE   assumes ascending sort}
  243.      n := 0;
  244.      s := UpCaseStr(st);
  245.      if (arrayused > 0) then
  246.           begin
  247.           found := false;
  248.           while (n < arrayused) and not found do
  249.                begin
  250.                inc(n);
  251.                if (s = arrayptr^[n].fetch) then found := true
  252.                else if (mode = 1) and (s < arrayptr^[n].fetch) then
  253.                                    found := true
  254.                else if (mode = 2) and (n < arrayused) then
  255.                     begin
  256.                     if (s > arrayptr^[n].fetch) and
  257.                        (s < arrayptr^[n+1].fetch) then
  258.                                    found := true;
  259.                     end;
  260.                end;
  261.           end;
  262.      if not found then n := 0;
  263.      linearsearch := n;
  264.      end;
  265.  
  266.  
  267. Procedure STRA_object.dump;
  268. var i  : integer;
  269.      begin
  270.      if arrayused < 1 then exit;
  271.      for i := 1 to arrayused do
  272.           begin
  273.           writeln(i:4,' [',arrayptr^[i].fetch,']  ');
  274.           end;
  275.      writeln('');
  276.      end;
  277.  
  278.  
  279. Procedure STRA_object.listpage(f,n,w : integer);
  280. var i  : integer;
  281.      begin
  282.      if (f > arrayused) or (arrayused < 1) then exit;
  283.      i := f;
  284.      if i < 1 then i := 1;
  285.      while (i < (f+n)) do
  286.           begin
  287.           writeln(leftstr(arrayptr^[i].fetch,w-1));
  288.           inc(i);
  289.           end;
  290.      end;
  291.  
  292.  
  293. Procedure STRA_object.save(fname : string);
  294. var i  : integer;
  295.     OK : boolean;
  296.     TEXTF : TFILE_object;
  297.      begin
  298.      if arrayused < 1 then exit;
  299.      TEXTF.init(fname,true);
  300.      for i := 1 to arrayused do
  301.           begin
  302.           ok := TEXTF.append(STRA_object.fetchN(i));
  303.           end;
  304.      TEXTF.done;
  305.      end;
  306.  
  307.  
  308. Procedure STRA_object.load(fname : string);
  309. var s : string;
  310.     OK : boolean;
  311.     TEXTF : TFILE_object;
  312.      begin
  313.      TEXTF.init(fname,false);
  314.      ok := TEXTF.opened;
  315.      while ok do
  316.           begin
  317.           ok := TEXTF.fetchnext(s);
  318.           if ok then ok := STRA_object.append(s);
  319.           end;
  320.      modified := false;
  321.      TEXTF.done;
  322.      end;
  323.  
  324.  
  325. Procedure STRA_object.loadsection(fname,sectiontag,sectionname : string);
  326. var secttag,sectname  : string[40];
  327.     sectlen   : integer;
  328.     ok, found : boolean;
  329.     s         : string;
  330.     TEXTF     : TFILE_object;
  331.      begin
  332.      found := false;
  333.      secttag  := UpcaseStr(sectiontag);
  334.      sectname := UpcaseStr(sectionname);
  335.      trim(sectname);
  336.      sectlen  := length(sectname);
  337.      TEXTF.init(fname,false);
  338.      ok := TEXTF.opened;
  339.      while ok do
  340.           begin
  341.           ok := TEXTF.fetchnext(s);
  342.           if ok then
  343.                begin
  344.                if secttag = leftstr(UpCaseStr(s),length(secttag)) then
  345.                      begin
  346.                      if found then
  347.                           begin
  348.                           found := false;
  349.                           ok := false;
  350.                           end
  351.                      else begin
  352.                           delete(s,1,length(secttag));
  353.                           RemoveLeading(s,' ');
  354.                           if leftstr(UpCaseStr(s),sectlen) = sectname then
  355.                                 found := true;
  356.                           end;
  357.                      end
  358.                else if found then ok := STRA_object.append(s);
  359.                end;
  360.           end;
  361.      modified := false;
  362.      TEXTF.done;
  363.      end;
  364.  
  365.  
  366.  
  367. {$R-}
  368.  
  369.  
  370. Procedure STRA_object.swap(i,j : integer);
  371. var sptr : stringptr;
  372.      begin
  373.      sptr := arrayptr^[i].strptr;
  374.      arrayptr^[i].strptr := arrayptr^[j].strptr;
  375.      arrayptr^[j].strptr := sptr;
  376.      modified := true;
  377.      end;
  378.  
  379.  
  380. procedure STRA_object.sort;
  381. var Gap,I,J,N : integer;
  382.     s1,s2      : stringptr;
  383.      begin
  384.      if arraysorted then exit;
  385.      N   := STRA_object.count;
  386.      Gap := N div 2;
  387.      while (Gap > 0) do
  388.          begin
  389.          I := Gap;
  390.          while (I < N) do
  391.               begin
  392.               J := I - Gap;
  393.               s1 := arrayptr^[J+Gap+1].strptr;
  394.               s2 := arrayptr^[J+1].strptr;
  395.               while (J >= 0) and (s1^ < s2^) do
  396.                    begin
  397.                    STRA_object.swap(J+1,J+Gap+1);
  398.                    dec(J,Gap);
  399.                    s1 := arrayptr^[J+Gap+1].strptr;
  400.                    s2 := arrayptr^[J+1].strptr;
  401.                    end;
  402.               inc(I);
  403.               end;
  404.          Gap:=Gap div 2;
  405.          end;
  406.      modified := true;
  407.      arraysorted := true;
  408.      end;
  409.  
  410.  
  411. {$R+}
  412.  
  413. Function STRA_object.binsearchEQ(st : string) : integer;  {exact match}
  414. var i,n,p : integer;
  415.     s1    : string;
  416.      begin
  417.      p := 0;
  418.      n := arrayused;
  419.      while (n > 1) do
  420.           begin
  421.           n := (n + 1) div 2;
  422.           if st = arrayptr^[p+n].strptr^ then
  423.                begin
  424.                binsearchEQ := (p+n);
  425.                exit;
  426.                end
  427.           else if st > arrayptr^[p+n].strptr^  then p := p + n;
  428.           end;
  429.      binsearchEQ := 0;
  430.      end;
  431.  
  432.  
  433. Function STRA_object.binsearchAPPROX(st : string) : integer;
  434.                                                 {first generic match}
  435. var i,n,p : integer;
  436.     s1    : string;
  437.      begin
  438.      p := 0;
  439.      n := arrayused;
  440.      while (n > 1) do
  441.           begin
  442.           n := (n + 1) div 2;
  443.           if st = arrayptr^[p+n].strptr^ then
  444.                begin
  445.                binsearchAPPROX := (p+n);
  446.                exit;
  447.                end
  448.           else if st > arrayptr^[p+n].strptr^  then p := p + n;
  449.           end;
  450.      if st = leftstr(arrayptr^[p+1].strptr^,length(st)) then
  451.           binsearchAPPROX := p+1
  452.      else binsearchAPPROX := 0;
  453.      end;
  454.  
  455.  
  456. Function STRA_object.BinSearchLE(st : string) : integer; {returns LE}
  457. var i,n,p : integer;
  458.     s1    : string;
  459.      begin
  460.      p := 0;
  461.      n := arrayused;
  462.      while (n > 1) do
  463.           begin
  464.           n := (n + 1) div 2;
  465.           if st = arrayptr^[p+n].strptr^ then
  466.                begin
  467.                BinSearchLE := (p+n);
  468.                exit;
  469.                end
  470.           else if st > arrayptr^[p+n].strptr^  then p := p + n;
  471.           end;
  472.      BinSearchLE := p;
  473.      end;
  474.  
  475.  
  476. Function STRA_object.BinSearchGE(st : string) : integer; {returns LE}
  477. var i,n,p : integer;
  478.     s1    : string;
  479.      begin
  480.      p := 0;
  481.      n := arrayused;
  482.      while (n > 1) do
  483.           begin
  484.           n := (n + 1) div 2;
  485.           if st = arrayptr^[p+n].strptr^ then
  486.                begin
  487.                BinSearchGE := (p+n);
  488.                exit;
  489.                end
  490.           else if st > arrayptr^[p+n].strptr^  then p := p + n;
  491.           end;
  492.      if p < arrayused then BinSearchGE := p+1
  493.      else BinSearchGE := 0;
  494.      end;
  495.  
  496.  
  497. Function STRA_object.Find(st : string) : integer;
  498. var n : integer;
  499.      begin
  500.      if arraysorted then n := STRA_object.binsearchEQ(st)
  501.      else n := STRA_object.linearfind(st);
  502.      Find := n;
  503.      end;
  504.  
  505.  
  506. Function STRA_object.Search(st : string; mode : byte) : integer;
  507. var n : integer;
  508.      begin
  509.      n := 0;
  510.      if arraysorted then
  511.           begin
  512.           case mode of
  513.               0 : n := STRA_object.binsearchEQ(st);
  514.               1 : n := STRA_object.binsearchGE(st);
  515.               2 : n := STRA_object.binsearchLE(st);
  516.               end;
  517.           end
  518.      else n := STRA_object.linearsearch(st,mode);
  519.      Search := n;
  520.      end;
  521.  
  522.  
  523. Function  STRA_object.insertstr(n : integer;st : string):boolean;
  524. { append the item to the array, then bubble down to position }
  525. var ok : boolean;
  526.     i  : integer;
  527.      begin
  528.      ok := STRA_object.append(st);
  529.      if ok then
  530.           begin
  531.           modified := true;
  532.           if (n+1) < count then
  533.                begin
  534.                for i := count-1 downto n+1 do swap(i+1,i);
  535.                end;
  536.           end;
  537.      insertstr := ok;
  538.      end;
  539.  
  540.  
  541. Function  STRA_object.deletestr(n : integer):boolean;
  542.  
  543. { for now, just bubble the item to the end, replace with
  544.     null string and decrement the count - this leaves some
  545.     heap garbage which I will ignore for now }
  546.  
  547. var ok : boolean;
  548.     i  : integer;
  549.      begin
  550.      if n <= count then
  551.           begin
  552.           if (n+1) < count then
  553.                begin
  554.                for i := n to count-1 do swap(i+1,i);
  555.                end;
  556.           ok := STRA_object.storeN(count,'');
  557.           dec(arrayused);
  558.           modified := true;
  559.           end;
  560.      deletestr := ok;
  561.      end;
  562.